package com.ekingstar.lss.commons.supper.dao.hibernate;

import java.io.Serializable;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.regex.Pattern;

import org.hibernate.Query;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;

import com.ekingstar.lss.commons.supper.LssRuntimeException;
import com.ekingstar.lss.commons.supper.dao.DaoSupper;
import com.ekingstar.lss.commons.supper.utils.query.LssCondition;
import com.ekingstar.lss.commons.supper.utils.query.LssLimit;
import com.ekingstar.lss.commons.supper.utils.query.LssQuery;
import com.sun.xml.internal.stream.Entity;

/**
 *	公司：金仕达多媒体
 *	作者：童弘成
 *	时间：2011-4-20 下午04:47:49
 *	描述：
 */
public class SupperDaoHibernate<ENTITY> extends HibernateDaoSupport implements DaoSupper<ENTITY> {

	public int delete(ENTITY entity) {
		this.getHibernateTemplate().delete(entity);
		return 1;
	}

	public int delete(String targetName,Serializable pk) {
		Object entity=this.getHibernateTemplate().get(targetName,pk);
		this.getHibernateTemplate().delete(entity);
		return 1;
	}

	
	public int delete(String targetName,List<LssCondition> conditions) {
		StringBuffer hql=new StringBuffer();
		hql.append("delete from ").append(targetName).append(" where ");
		List<Object> values=new ArrayList<Object>();
		
		for (int i = 0; i < conditions.size(); i++) {
			LssCondition condition=conditions.get(i);
			if(i==0){
				hql.append(" ").append(condition.getContent());
				values.addAll(condition.getValues());
			}else{
				hql.append(" ").append(condition.getType());
				hql.append(" ").append(condition.getContent());
				values.addAll(condition.getValues());
			}
		}
		Query query= this.getSession().createQuery(hql.toString());
		
		this.setParams(query, values);
		
		return query.executeUpdate();
	}

	protected void setParams(Query query,List<Object> params){
		for (int i = 0; i < params.size(); i++) {
			Object param=params.get(i);
			if(param instanceof Integer){
				Integer temp=(Integer) param;
				query.setInteger(i+1, temp.intValue());
			}else if(param instanceof Long){
				Long temp=(Long) param;
				query.setLong(i+1, temp.longValue());
			}else if(param instanceof Float){
				Float temp=(Float) param;
				query.setFloat(i+1, temp);
			}else if(param instanceof Double){
				Double temp=(Double) param;
				query.setDouble(i+1, temp);
			}else if(param instanceof Date){
				Date temp=(Date) param;
				query.setTimestamp(i+1, temp);
			}else if(param instanceof String){
				String temp=String.valueOf(param);
				query.setString(i+1, temp);
			}else{
				query.setString(i+1, String.valueOf(param));
			}
		}
	}
	
	public List<Entity> getList(LssQuery query) {
		Query hquery=this.getSession().createQuery(query.getContent());
		List<LssCondition> conditions=query.getConditions();
		List<Object> params=new ArrayList<Object>();
		for (int i = 0; i < conditions.size(); i++) {
			params.add(conditions.get(i).getValues());
		}
		this.setParams(hquery, params);
		if(query.getLimit()!=null){
			LssLimit limit=query.getLimit();
			hquery.setFirstResult((int)limit.getFirstRow());
			hquery.setMaxResults((int)limit.getMaxLength());
		}
		return hquery.list();
	}

	public int insert(ENTITY entity) {
		this.getHibernateTemplate().save(entity);
		return 1;
	}

	public int save(ENTITY entity) {
		this.getHibernateTemplate().saveOrUpdate(entity);
		return 1;
	}

	public int update(ENTITY entity, Serializable pk) {
		this.getHibernateTemplate().update(entity);
		return 0;
	}

	public int update(ENTITY entity, List<LssCondition> conditions) {
		StringBuffer hql=new StringBuffer();
		
		Query query=this.getSession().createQuery(hql.toString());
		hql.append("update ").append(entity.getClass().getName()).append(" set");
		
		List<String> properties=this.getPropertiesName(entity);
		List<Object> values=this.getPropertiesValue(entity);
		for (int i = 0; i < properties.size(); i++) {
			if(i==0){
				hql.append(" ").append(properties.get(i)).append("=?");
			}else{
				hql.append(",").append(properties.get(i)).append("=?");
			}
		}
		List<Object> params=new ArrayList<Object>();
		params.addAll(values);
		for (int i = 0; i < conditions.size(); i++) {
			LssCondition condition=conditions.get(i);
			if(i==0){
				hql.append(" ").append(condition.getContent());
				params.addAll(condition.getValues());
			}else{
				hql.append(" ").append(condition.getType());
				hql.append(" ").append(condition.getContent());
				params.addAll(condition.getValues());
			}
		}
		this.setParams(query, params);
		return query.executeUpdate();
	}
	
	protected List<String> getPropertiesName(ENTITY entity){
		List<String> properties=new ArrayList<String>();
		Method[] method=entity.getClass().getMethods();
		Pattern p=Pattern.compile("^get[A-Z]\\w+$");
		for (int i = 0; i < method.length; i++) {
			if(p.matcher(method[i].getName()).matches()&&method[i].getParameterTypes().length==0){
				String name=method[i].getName();
				properties.add(name.substring(0,1).toLowerCase()+name.substring(1,name.length()));
			}
		}
		return properties;
	}
	
	protected List<Object> getPropertiesValue(ENTITY entity){
		List<Object> properties=new ArrayList<Object>();
		Method[] method=entity.getClass().getMethods();
		Pattern p=Pattern.compile("^get[A-Z]\\w+$");
		try{
			for (int i = 0; i < method.length; i++) {
				if(p.matcher(method[i].getName()).matches()&&method[i].getParameterTypes().length==0){
					properties.add(method[i].invoke(entity));
				}
			}
		}catch(Exception e){
			throw new LssRuntimeException(e);
		}
		return properties;
	}

	public ENTITY getEntity(Serializable id) {
		return null;
	}

	public ENTITY getEntityByUk(Serializable uk) {
		return null;
	}
}
